﻿using System;
using System.Collections.Generic;
using System.Linq;
//using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
//using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
//using System.Windows.Media.Animation;
//using System.Windows.Shapes;
using Microsoft.Phone.Controls;
//using Microsoft.Phone.Info;
//using System.Text;
using Microsoft.Phone.Shell;
using System.Collections;
using System.Collections.ObjectModel;
using Microsoft.Advertising.Mobile.UI;
using Microsoft.Phone.Tasks;
using Microsoft.Phone.BackgroundAudio;
using System.IO;
using System.Windows.Media.Imaging;
using DailyBread.DataServiceReference;
using System.Diagnostics;
//using Microsoft.Phone.Notification;
using System.IO.IsolatedStorage;
using System.Xml.Linq;
using System.Windows.Navigation;
using System.Threading;


namespace DailyBread
{
    public partial class MainPage : PhoneApplicationPage
    {
        public App currentApp { get; set; }
        
        #region comments private variables
        //private int numberofComments = 0;
        private ListBoxItem commentListBoxItem;
        public class CommentDisplay
        {
            public CommentDisplay(string Text, DateTime localTime)
            {
                Comment = Text;
                DateForDisplay = localTime;
            }

            public string Comment { get; set; }
            public DateTime DateForDisplay { get; set; }

        }
        private ObservableCollection<CommentDisplay> comments = new ObservableCollection<CommentDisplay>();
        #endregion

        #region Notification service private variables
        //private HttpNotificationChannel httpChannel;
        const string channelName = "DailyBreadUpdatesChannel";
        const string fileName = "PushNotificationsSettings.dat";
        const int pushConnectTimeout = 30;
        #endregion

        // Constructor
        public MainPage()
        {
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(Default_Loaded);
            currentApp = ((App)Application.Current);
            if (currentApp.appBarEventsRegistered == false)
            {   // check so that we don't add the event handlers multiple times
                (ApplicationBar.Buttons[0] as ApplicationBarIconButton).Click += new EventHandler(ApplicationBarHome_OnClick);
                (ApplicationBar.Buttons[1] as ApplicationBarIconButton).Click += new EventHandler(ApplicationBarPrevious_OnClick);
                (ApplicationBar.Buttons[2] as ApplicationBarIconButton).Click += new EventHandler(ApplicationBarNext_OnClick);
                (ApplicationBar.Buttons[3] as ApplicationBarIconButton).Click += new EventHandler(ApplicationBarAmen_OnClick);
                currentApp.appBarEventsRegistered = true;
            }


            //if (!TryFindChannel())
            //    DoConnect();
            //AdControl.TestMode = false;
        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            if (PlayState.Playing == BackgroundAudioPlayer.Instance.PlayerState)
            {
                PlayButton.Source = new BitmapImage(new Uri("images/pause.png", UriKind.Relative));
            }
            else
            {
                PlayButton.Source = new BitmapImage(new Uri("images/play.png", UriKind.Relative));
            }
        }

        private void LoadBackgroundImage()
        {
            SolidColorBrush backgroundBrush = App.Current.Resources["PhoneBackgroundBrush"] as SolidColorBrush;
            if (currentApp.setting.LightBG == true)
            {   // with light background, don't use the bing image
                PanoramaControl.Background = backgroundBrush;
            }
            else
            {
                if (currentApp.setting.UseSolidBG == true)
                {
                    PanoramaControl.Background = backgroundBrush;
                }
                else
                {
                    Uri imageUri = Util.GetImageUrl(currentApp.context.currentDisplayDate);
                    ImageBrush brush = new ImageBrush
                    {
                        ImageSource = new BitmapImage(imageUri)
                    };
                    brush.Stretch = Stretch.UniformToFill;

                    PanoramaControl.Background = brush;
                }
            }
        }

        private void Default_Loaded(object sender, RoutedEventArgs e)
        {
            Reload();    

            ResourceDictionary res = App.Current.Resources;
            SolidColorBrush bgBrush = res["TransparentBackground"] as SolidColorBrush;
            bgBrush.Opacity = currentApp.setting.BGShade;

            //upload logs
            ThreadPool.QueueUserWorkItem(o => Util.UploadLogToAzure());

            // pre fetch next 3 days bread
            for (int i = 1; i <= 3; i++)
            {
                DateTime prefetechDate = System.DateTime.Today.AddDays(i);
                ThreadPool.QueueUserWorkItem(o => PreFetchBread(prefetechDate));
            }
        }

        public void Reload()
        {
            LoadBackgroundImage();
            ToggleBreadProgressIndicator(false);
            #region get favorite count
            // Get Fav Count and display it if there's any
            Util.GetFavCountFromAzure(currentApp.context.currentDisplayDate,
                delegate(string favorites)
                {
                    try
                    {
                        bool state = false;
                        if (favorites != null)
                        {
                            int count = 0;
                            bool fSuccess = int.TryParse((string)favorites, out count);

                            if (fSuccess && count != 0)
                            {
                                currentApp.context.FavoriteCount = count;
                                FavCount.Text = count.ToString();
                                state = true;
                            }
                        }
                        ToggleFavCount(state);
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine(ex.ToString());
                        ToggleFavCount(false);
                    }
                },
                delegate(Exception ex)
                {
                    Debug.WriteLine(ex.ToString());
                    ToggleFavCount(false);
                });

            // set fav state to false to start with
            ToggleFav(false);
            #endregion

            // check to see if the verse is a personal favorite
            DailyVerse dv = Util.FindAmen(currentApp.context.currentDisplayDate);
            if (dv != null && !String.IsNullOrEmpty(dv.breadContent) && !String.IsNullOrEmpty(dv.breadUri))
            {
                if (dv.personalFav)
                {
                    ToggleFav(true);
                }

                // poplulate UI elements
                Article.Text = dv.breadContent;
                Article.FontSize = currentApp.setting.TextFontSize;
                Verse.Text = dv.verseContent;
                Verse.FontSize = currentApp.setting.TextFontSize;
                RefBible.Text = dv.verseName;
                RefBibleOnCommentsPage.Text = dv.breadName;
                BreadName.Text = dv.breadName;

                // populate context
                currentApp.context.VerseName = dv.verseName; // "john 3:7-16"
                currentApp.context.VerseContent = dv.verseContent;
                currentApp.context.BreadContent = dv.breadContent;
                currentApp.context.BreadName = dv.breadName; // "the wonder of light"
                currentApp.context.ArticleVerse = dv.articleVerse;  // "No man ever spoke like this Man!  John 7:46"
                currentApp.context.BreadUri = new Uri(dv.breadUri);

            }
            else
            {
                // set loading state to true since we'll start the http request
                ToggleBreadProgressIndicator(true);
                FetchBread();
            }

            // Reset play state and track
            if (PlayState.Playing == BackgroundAudioPlayer.Instance.PlayerState)
            {
                BackgroundAudioPlayer.Instance.Pause();
                PlayButton.Source = new BitmapImage(new Uri("images/play.png", UriKind.Relative));
            }
            SetPlayTrack();
            BackgroundAudioPlayer.Instance.Pause();

            // get comments data
            ShowComments();
        }

        // pre fetch future bread and cache it
        private void PreFetchBread(DateTime date)
        {
            // if exists, do nothing
            if (Util.FindAmen(date) != null)
                return;

            AppContext tmpCtx = new AppContext(date);
            Util.GetContentFromAzure(date,
                delegate(BreadData content)
                {
                    tmpCtx.BreadName = content.BreadName;
                    tmpCtx.BreadContent = content.BreadContent;
                    tmpCtx.VerseName = content.VerseName;
                    tmpCtx.VerseContent = content.VerseContent;
                    tmpCtx.ArticleVerse = content.ArticleVerse;
                    tmpCtx.BreadUri = new Uri(content.BreadUri);
                    // cache 
                    if (!String.IsNullOrEmpty(tmpCtx.BreadContent))
                    { // only cache it if we get the daily bread content
                        Util.RecordAmen(tmpCtx, false);
                    }
                },
                delegate(Exception ex)
                {
                    Debug.WriteLine(ex.ToString());
                });
        }

        // Fetch today's bread
        private void FetchBread()
        {
             Util.GetContentFromAzure(currentApp.context.currentDisplayDate,
                delegate(BreadData content)
                {
                    currentApp.context.BreadName = content.BreadName;
                    currentApp.context.BreadContent = content.BreadContent;
                    currentApp.context.VerseName = content.VerseName;
                    currentApp.context.VerseContent = content.VerseContent;
                    currentApp.context.ArticleVerse = content.ArticleVerse;
                    currentApp.context.BreadUri = new Uri(content.BreadUri);

                    // set loading state to false since we are ready to render the text
                    ToggleBreadProgressIndicator(false);
                    BreadName.Text = currentApp.context.BreadName;
                    RefBibleOnCommentsPage.Text = currentApp.context.BreadName;
                    RefBible.Text = currentApp.context.VerseName;
                    Article.Text = currentApp.context.BreadContent;
                    Article.FontSize = currentApp.setting.TextFontSize;
                    Verse.Text = currentApp.context.VerseContent;
                    Verse.FontSize = currentApp.setting.TextFontSize;

                    // cache or save as favorite
                    if (!String.IsNullOrEmpty(currentApp.context.BreadContent))
                    { // only cache it if we get the daily bread content
                        Util.RecordAmen(currentApp.context, currentApp.context.IsFav);
                    }
                },
                delegate(Exception ex)
                {
                    BreadProgressBar.IsIndeterminate = false;
                    VerseProgressBar.IsIndeterminate = false;
                    Article.Text = "Error retrieving Daily Bread content.";
                    Verse.Text = "Error retrieving bible verse.";
                    Article.Visibility = Visibility.Visible;
                    Verse.Visibility = Visibility.Visible;
                    Debug.WriteLine(ex.ToString());
                });
        }

        #region application bar actions
        private void ApplicationBarHome_OnClick(object sender, EventArgs e)
        {
            currentApp.context = new AppContext(System.DateTime.Today);
            Util.AddToLog("HomeButton");
            Reload();
        }

        private void ApplicationBarNext_OnClick(object sender, EventArgs e)
        {
            currentApp.context = new AppContext(currentApp.context.currentDisplayDate.AddDays(1));
            Util.AddToLog("NextButton");

            Reload();
        }

        private void ApplicationBarPrevious_OnClick(object sender, EventArgs e)
        {
            currentApp.context = new AppContext(currentApp.context.currentDisplayDate.AddDays(-1));
            Util.AddToLog("PrevButton");

            Reload();
        }

        private void ApplicationBarAmen_OnClick(object sender, EventArgs e)
        {
            if (currentApp.context.IsFav)
                return;
            
            try
            {
                Util.AddToLog("FavButton");

                Util.RecordAmen(currentApp.context, true);
                ToggleFav(true);
                ToggleFavCount(true);
                FavCount.Text = currentApp.context.FavoriteCount.ToString();
            }
            catch(Exception ex)
            {
                Debug.WriteLine(ex.ToString());
            }
        }

        #endregion

        #region comment panorama item
        private void PostButton_Click(object sender, RoutedEventArgs e)
        {
            string comment = CommentBox.Text;

            // if the comment box is empty, do nothing
            if (String.IsNullOrEmpty(comment) || string.Compare("Share your thoughts...", comment, StringComparison.OrdinalIgnoreCase) == 0)
                return;

            Util.AddToLog("PostComment");

            ToggleCommentProgressIndicator(true);
            Util.SaveCommentToAzure(currentApp.context.currentDisplayDate, comment,
                delegate(string result)
                {
                    SetCommentBoxWatermark();
                    ShowComments();
                },
                delegate(string msg)
                {
                    CommentProgressBar.IsIndeterminate = false;
                    Debug.WriteLine(msg);
                    MessageBlock.Text = "Comment posting failed.  Please try again later.";
                    MessageBlock.Visibility = Visibility.Visible;
                    PostButton.Visibility = Visibility.Visible;
                    SetCommentBoxWatermark();
                });
        }

        private void ShowComments()
        {
            ToggleCommentProgressIndicator(true);

            Util.GetCommentsFromAzure(currentApp.context.currentDisplayDate,
                delegate(IEnumerable<CommentData> lists)
                {
                    ToggleCommentProgressIndicator(false);
                    comments.Clear();
                    foreach (CommentData cmt in lists)
                    {
                        long tick = long.Parse(cmt.RowKey.Substring(1, 19));
                        System.DateTime displaytime = new System.DateTime(System.DateTime.MaxValue.Ticks - tick);
                        comments.Add(new CommentDisplay(cmt.Comment, displaytime.ToLocalTime()));
                    }
                    if (comments != null && comments.Count != 0)
                    {
                        CommentList.ItemsSource = comments;
                        CommentList.Visibility = Visibility.Visible;
                        MessageBlock.Visibility = Visibility.Collapsed;
                        CommentList.ScrollIntoView(CommentList.Items.First());
                        CommentList.UpdateLayout();

                    }
                    else
                    {
                        MessageBlock.Text = "No comments yet. Be the first one to comment.";
                        MessageBlock.Visibility = Visibility.Visible;
                        CommentList.Visibility = Visibility.Collapsed;
                    }                 
                },
                delegate(Exception ex)
                {
                    Debug.WriteLine(ex.InnerException.Message);
                    MessageBlock.Text = "Error retrieving comments.";
                    MessageBlock.Visibility = Visibility.Visible;
                    CommentList.Visibility = Visibility.Collapsed;
                    CommentProgressBar.IsIndeterminate = false;
                });

        }

        private void CommentBox_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            CommentBox.Text = "";
        }

        private void CommentBox_GotFocus(object sender, RoutedEventArgs e)
        {
            if (CommentBox.Text == "Share your thoughts...")
            {
                CommentBox.Text = "";
            }
            CommentBox.Foreground = App.Current.Resources["PhoneTextBoxForegroundBrush"] as Brush;

        }

        private void CommentBox_LostFocus(object sender, RoutedEventArgs e)
        {
            if (CommentBox.Text == String.Empty)
            {
                SetCommentBoxWatermark();
            }
        }

        private void SetCommentBoxWatermark()
        {
            CommentBox.Text = "Share your thoughts...";
            SolidColorBrush Brush2 = new SolidColorBrush();
            Brush2.Color = Colors.Gray;
            CommentBox.Foreground = Brush2;
        }

        private void Comment_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            Point tmpPoint = e.GetPosition(null);
            commentListBoxItem = GetListBoxItem(tmpPoint);
        }

        private ListBoxItem GetListBoxItem(Point pt)
        {
            ListBoxItem item = null;
            List<UIElement> oControls = (List<UIElement>)VisualTreeHelper.FindElementsInHostCoordinates(pt, this);
            foreach (UIElement ctrl in oControls)
            {
                if (ctrl is ListBoxItem)
                {
                    item = (ListBoxItem)ctrl;
                    break;
                }

            }
            return item;
        }

        private void CommentContextMenuDelete_Click(object sender, RoutedEventArgs e)
        {
            return; // disabled this functionality

            //CommentData comment = commentListBoxItem.Content as CommentData;
            //Util.AddToLog("DeleteComment");

            //CommentProgressBar.IsIndeterminate = true;
            //Util.RemoveComment(comment,
            //    delegate(CommentData cmt)
            //    {  
            //        // if azure removal is successful, remove it from UI
            //        int index = comments.IndexOf(comment);
            //        comments.RemoveAt(index);
            //        CommentProgressBar.IsIndeterminate = false;
            //    },
            //    delegate(Exception ex)
            //    {
            //        Debug.WriteLine(ex.InnerException.Message);
            //        MessageBlock.Text = "Error deleting comment.";
            //        MessageBlock.Visibility = Visibility.Visible;
            //        CommentList.Visibility = Visibility.Collapsed;
            //        CommentProgressBar.IsIndeterminate = false;
            //    });
        }
        #endregion

        #region state management
        private void ToggleFavCount(bool on)
        {
            if (on)
            {
                FavCount.Visibility = Visibility.Visible;
                Thumbup.Visibility = Visibility.Visible;
            }
            else
            {
                FavCount.Visibility = Visibility.Collapsed;
                Thumbup.Visibility = Visibility.Collapsed;
            }
        }

        private void ToggleFav(bool on)
        {
            if (on)
            {
                FavImg.Visibility = Visibility.Visible;
                FavImg2.Visibility = Visibility.Visible;
                FavImg3.Visibility = Visibility.Visible;
                currentApp.context.IsFav = true;
            }
            else
            {
                FavImg.Visibility = Visibility.Collapsed;
                FavImg2.Visibility = Visibility.Collapsed;
                FavImg3.Visibility = Visibility.Collapsed;
                currentApp.context.IsFav = false;
            }
        }

        private void ToggleBreadProgressIndicator(bool on)
        {
            if (on)
            {   // turn the progress indicator on
                BreadProgressBar.IsIndeterminate = true;
                BreadProgressBar.Visibility = Visibility.Visible;
                VerseProgressBar.IsIndeterminate = true;
                VerseProgressBar.Visibility = Visibility.Visible;
                Article.Visibility = Visibility.Collapsed;
                Verse.Visibility = Visibility.Collapsed;
                RefBible.Visibility = Visibility.Collapsed;
            }
            else
            {
                BreadProgressBar.IsIndeterminate = false;
                BreadProgressBar.Visibility = Visibility.Collapsed;
                VerseProgressBar.IsIndeterminate = false;
                VerseProgressBar.Visibility = Visibility.Collapsed;
                Article.Visibility = Visibility.Visible;
                Verse.Visibility = Visibility.Visible;
                RefBible.Visibility = Visibility.Visible;
            }
        }

        private void ToggleCommentProgressIndicator(bool on)
        {
            if (on)
            {
                CommentProgressBar.IsIndeterminate = true;
                CommentList.Visibility = Visibility.Collapsed;
                PostButton.Visibility = Visibility.Collapsed;
            }
            else
            {
                CommentProgressBar.IsIndeterminate = false;
                CommentList.Visibility = Visibility.Visible;
                PostButton.Visibility = Visibility.Visible;
            }

        }
        #endregion

        #region Tracing and Status Updates
        private void Trace(string message)
        {
            Debug.WriteLine(message);
        }
        #endregion

        #region audio
        private void PlayButton_Click(object sender, MouseButtonEventArgs e)
        {
            if (PlayState.Playing == BackgroundAudioPlayer.Instance.PlayerState)
            {
                Util.AddToLog("pause audio");
                PlayButton.Source = new BitmapImage(new Uri("images/play.png", UriKind.Relative));
                BackgroundAudioPlayer.Instance.Pause();
            }
            else
            {
                Util.AddToLog("play audio");
                PlayButton.Source = new BitmapImage(new Uri("images/pause.png", UriKind.Relative));

                if (BackgroundAudioPlayer.Instance.Track == null)
                {
                    SetPlayTrack();
                }
                BackgroundAudioPlayer.Instance.Play();
            }
        }

        private void SetPlayTrack()
        {
            DateTime currentDate = currentApp.context.currentDisplayDate;
            string audioLocation = string.Format("http://cdn.rbc.org/odb/{0}/{1}/odb-{2}-{3}-{4}.mp3",
                currentDate.Year.ToString(),
                currentDate.Month.ToString("d2"),
                currentDate.Month.ToString("d2"),
                currentDate.Day.ToString("d2"),
                (currentDate.Year - 2000).ToString());

            AudioTrack track = new AudioTrack(new Uri(audioLocation, UriKind.Absolute),
                currentApp.context.BreadName,
                "Our Daily Bread",
                "Our Daily Bread",
                null);
            BackgroundAudioPlayer.Instance.Track = track;
        }
        #endregion
    }
}
    